/*  
    一：基本介绍
        es：分布式搜索引擎，支持存储数据和索引数据，分布式，零配置，自动发现，索引自动分片，索引副本机制，
        restful风格接口，多数据源，自动搜索负载等。
    二：和数据库的区别
        1、组织数据的方式不同
        数据库组织数据和es组织数据对比
            库    ----> 索引
            表    ----> 类型
            项    ----> 文档
            字段  ----> 字段
        2、搜索数据时，数据库是根据字段构建的索引来检索，如果是模糊匹配，那么此时数据库就要一一遍历每一项
        而es是把文档中的指定字段进行分词（ik或者其他分词器）构建索引（映射），当查询时，无论是模糊还是精确查询
        都可以定位到文档，所以很适合搜索
*/

/* 
    一、项目中es操作的基本分类
        1、创建索引 
        2、删除索引 
        3、新增数据 
        4、查询数据
    二、基本使用接口（因为c++版本的API库很少，所以采用elasticlient库）
    1、创建索引 && 新增数据
    cpr::Response index(const std::string &indexName, const std::string &docType, const std::string &id,
                        const std::string &body, const std::string &routing = std::string());
    indexName: 索引名字
    dicType: 文档类型（7.x版本之后弃用），也就是说每个索引中只有一种类型
    id: 创建索引的时候要指定索引，新增数据的时候也要指定索引，两者的id区别是：
        索引id是索引的一个标识，如果索引名相同，id相同则不会创建新的索引，索引id没有多大意义
        数据id是存储的文档都有一个唯一的id。通过这个id，你可以快速检索、更新或删除文档，
        如果两者新增数据id相同，那么第二次就相当于修改数据
        无论是索引id还是新增数据的文档id，如果不指定id，会在插入文档时自动生成一个。（索引id采用缺省值，文档id我们采用自己指定id）
    body: 请求正文，json格式的字符串
    routing: 路由值，路由用于将文档分配到特定的分片上。这在需要对特定文档进行高效读写操作时非常有用。
             如果不提供路由值，Elasticsearch会根据文档id来决定其存储位置。(可联想redis集群中的分片)

    2、删除索引
    pr::Response remove(const std::string &indexName, const std::string &docType, const std::string &id,
                        const std::string &routing = std::string());
    删除时文档id不能为空
    3、搜索
    cpr::Response search(const std::string &indexName, const std::string &docType, 
                        const std::string &body, const std::string &routing = std::string());

    4、客户端构造
    explicit Client(const std::vector<std::string> &hostUrlList, std::int32_t timeout = 6000);
    hostRrlList：elasticsearch服务集群中每个节点的url，注意url地址后面要跟根目录

    5、响应的主要成员
    namespace cpr
    {
        class Response
        {
        public:
            long status_code{};
            std::string text{};
        }
    }
*/

#include <elasticlient/client.h>
#include <cpr/cpr.h>
#include <iostream>

/*
    搜索数据测试
*/
int main()
{
    // 1、创建客户端
    elasticlient::Client client({"http://127.0.0.1:9200/"}); // 主要web根目录一定不能少

    // 2、发起搜索请求并打印响应状态码和响应正文
    try
    {
        // 需要对下面代码捕获异常，防止服务请求失败导致整个程序异常
        cpr::Response rsp = client.search("user", "_doc", R"({"query": {"match_all":{}}})");
        std::cout << rsp.status_code << std::endl;
        std::cout << rsp.text << std::endl;
    }
    catch(std::exception& e)
    {
        std::cout << "请求失败:" << e.what() << std::endl;
        return -1;
    }

    return 0;
}



